<?php

declare(strict_types=1);

namespace App\Common\Handler;

use App\Sys;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Exception\MethodNotAllowedHttpException;
use Hyperf\HttpMessage\Exception\NotFoundHttpException;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;
use Zms\Exception\BasicsException;
use Zms\Exception\ExceptionCode;
use Zms\Exception\PrintException;
use Zms\Unit\Json;

/**
 * 接口项目异常管理器.
 */
class ApiHandler extends ExceptionHandler
{
    public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface
    {
        $this->stopPropagation();
        if ($throwable instanceof BasicsException) {// 自定义异常类
            $body = $this->stream($throwable->getCode(), $throwable->getMessage());
        } elseif ($throwable instanceof MethodNotAllowedHttpException) {
            $body = $this->stream(ExceptionCode::ERROR, '无效的访问方式');
        } elseif ($throwable instanceof NotFoundHttpException) {
            $body = $this->stream(ExceptionCode::NOT_FOUND, '无效的接口');
        } elseif ($throwable instanceof PrintException) {
            $body = new SwooleStream($throwable->getData());
        } else {
            Sys::log('exceptions', 'admin')->error($throwable->getMessage(), [
                'exceptions' => ['file' => $throwable->getFile(), 'line' => $throwable->getLine(), 'class' => $throwable::class],
            ]);
            $body = $this->stream(ExceptionCode::ERROR, '服务发生错误');
        }
        return $response->withHeader('content-type', 'application/json; charset=utf-8')->withStatus(200)->withBody($body);
    }

    /**
     * 生成响应体.
     */
    public function stream(int $code, string $msg): SwooleStream
    {
        return new SwooleStream(Json::encode(['code' => $code, 'msg' => $msg], JSON_UNESCAPED_UNICODE));
    }

    public function isValid(Throwable $throwable): bool
    {
        return true;
    }
}
